package com.bestom.bestoma10demo;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.text.Editable;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;

/**
 * @author bestom
 */
public class MainActivity extends AppCompatActivity {

    private Context mContext;
    private String upView = "up_view";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = this;
        SharedPreferencesUtil.init(this);
        initView();
        initData();
        initReceiver();
    }

    private void initReceiver() {
        IntentFilter upViewFilter = new IntentFilter();
        upViewFilter.addAction(upView);
        mContext.registerReceiver(mReceiver, upViewFilter);

        // listen tethering status
        IntentFilter autostateFilter=new IntentFilter();
        autostateFilter.addAction("com.bestom.autostate");
        registerReceiver(new tetherReceiver(),autostateFilter);

        // listen net
        IntentFilter netFilter = new IntentFilter();
        netFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        NetworkStateReceiver networkChangeReceiver = new NetworkStateReceiver();
        registerReceiver(networkChangeReceiver, netFilter);

        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SET_TIME}, 123);
    }


    @Override
    protected void onResume() {
        super.onResume();
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                time.setText(String.format("System Time: %s", mDateVTime.transform("yyyy-MM-dd HH:mm:ss", System.currentTimeMillis())));
                mHandler.postDelayed(this, 1000);
            }
        }, 1000);
    }

    private ScrollView mScrollView;
    private TextView textView;
    private TextView time;
    private TextView isHaveNet;
    private EditText ipServerEt;

    private void initView() {
        textView = findViewById(R.id.textView);
        time = findViewById(R.id.time);
        mScrollView = findViewById(R.id.scrollView);
        isHaveNet = findViewById(R.id.is_have_net);
        ipServerEt = findViewById(R.id.ip_server_et);
        findViewById(R.id.save_ip_server).setOnClickListener(v -> {
            String text = ipServerEt.getText().toString().trim();
            if (text.isEmpty()){
                Toast.makeText(getApplicationContext(),"Cannot be null. Please reenter",Toast.LENGTH_SHORT).show();
            }else {
                NetworkStateListener.ipServer = text;
                SharedPreferencesUtil.getInstance().putValue("ip_server",text);
            }
        });

        findViewById(R.id.clear).setOnClickListener(v -> textView.setText(""));

        findViewById(R.id.refresh).setOnClickListener(v -> refreshNet());
    }

    @SuppressLint("HandlerLeak")
    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1) {
                textView.append(msg.obj + "\n");
                scrollToBottom(textView);
            }
        }
    };
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            if (upView.equals(intent.getAction())) updateView(intent.getStringExtra(upView));
        }
    };

    private void updateView(String info) {
        Message message = new Message();
        message.what = 1;
        message.obj = info;
        mHandler.sendMessage(message);
    }

    private void scrollToBottom(final View view) {

        mHandler.post(() -> {
            if (mScrollView == null || view == null) return;
            int offset = view.getMeasuredHeight() - mScrollView.getMeasuredHeight();
            if (offset < 0) offset = 0;
            //scrollview Start rolling
            mScrollView.scrollTo(0, offset);
        });
    }

    private DateVTime mDateVTime;
    private Audio mAudio;
    private NetworkStateListener mNetworkStateListener;
    private void initData() {
        mDateVTime = DateVTime.getInstance();
        mAudio = Audio.getInstance(mContext);
        String ipServer = (String) SharedPreferencesUtil.getInstance().getValue("ip_server", "www.baidu.com");
        NetworkStateListener.ipServer = ipServer;
        ipServerEt.setText(ipServer);

        mNetworkStateListener = new NetworkStateListener(onOff -> runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (onOff){
                    isHaveNet.setText("network available.");
                    isHaveNet.setTextColor(Color.GREEN);
                }else {
                    isHaveNet.setText("network unavailable or ip error.");
                    isHaveNet.setTextColor(Color.RED);
                }
                refreshNet();
            }
        }));
    }

    /**
    * Refresh the connection mode, GET, DNS
    * */
    private void refreshNet(){
        updateView("Current networking mode : " + NetworkStateReceiver.getNetStatus(mContext));

        NetWorkUtils.isNetWorkAvailableOfGet("https://www.baidu.com", available -> {
            if (available) {
                updateView("use GET requests https://www.baidu.com is OK");
            } else {
                updateView("use GET requests https://www.baidu.com is Fail");
            }
            return 0;
        });

        NetWorkUtils.isNetWorkAvailableOfDNS(NetworkStateListener.ipServer, available -> {
            if (available) {
                updateView("use DNS resolution " + NetworkStateListener.ipServer + " is OK");
            } else {
                updateView("use DNS resolution " + NetworkStateListener.ipServer + " is Fail");
            }
            return 0;
        });
    }

    public void setClock(View view) {
        mDateVTime.setClock(mContext);
    }

    public void transForm(View view) {
        mContext.startActivity(new Intent(Settings.ACTION_DATE_SETTINGS));
    }
    /**It needs to be added in the manifest file,(android.uid.system) and sign package firmware, otherwise it will flash back*/
    public void setTime(View view) {
        mDateVTime.setTime(mContext, 12, 24);
        updateView("set Time to 12:24");
    }
    /**It needs to be added in the manifest file,(android.uid.system) and sign package firmware, otherwise it will flash back*/
    public void setDate(View view) {
        mDateVTime.setDate(mContext, 2020, 10, 11);
        updateView("set Date to 2020/11/11");
    }

    public void setWifi(View view) {
        mContext.startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
    }

    public void getNetInfo(View view) {
        CommandExec.CommandResult result = CommandExec.execCommand("ifconfig\n", false);
        Log.i("tag", "result:" + result.successMsg);
        String[] strings = result.successMsg.split("  +");
        for (String info : strings){
            updateView(info.trim());
        }
    }
    private ArrayList<NetworkInterface> getNetworkInterface(){
        ArrayList<NetworkInterface> mList = new ArrayList<>();
        // Gets all the network interfaces for the local device
        Enumeration<NetworkInterface> enumerationNi;
        try {
            enumerationNi = NetworkInterface.getNetworkInterfaces();
            while (enumerationNi.hasMoreElements()){
                mList.add(enumerationNi.nextElement());
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return mList;
    }
    public void setCallVolume(View view) {
        mAudio.setMediaVolume(10);
    }

    public void setMediaVolume(View view) {
        mAudio.setCallVolume(5);
    }

    @Override
    protected void onDestroy() {
        mNetworkStateListener.release();
        super.onDestroy();
    }
}